Skip to content

4.1 配置

📝 模块更新日志 新特性*

+ 新增 配置模块 `IgnoreConfigurationFiles` 支持完整的文件通配符 4\.8\.8\.22 ⏱️2023\.05\.25 [\#I78ABL](https://gitee.com/dotnetchina/Furion/issues/I78ABL)
  • 问题修复

    • 修复 监听配置文件更改出现多次触发问题 4.9.5.13 ⏱️2024.09.29 feb85d2

自定义配置特别注意如:xxxx.json,必须在 VS Studio 中右键属性设置 复制 输出目录为 如果较新则复制,生成操作为:内容

如果 .json 文件配置在多个项目层,也必须保证命名唯一,不然编译后出现相互覆盖的情况。

中文乱码问题默认情况下,.json 文件并未采用 utf-8 编码,所以如果存在中文读取后就会出现乱码情况,这时候,只需要修改 .json 文件编码为 utf-8 即可。

4.1.1 什么是配置

简单来说,配置将系统应用可动态调配的选项放在统一地方管理,通过不同的配置让系统做出动态调整。

ASP.NET Core 应用程序启动时默认加载 启动项目 下的 appsettings.json 作为应用配置。同时还支持不同的运行环境加载对应的配置文件,如:

  • Development:加载 appsettings.Development.json
  • Staging:加载 appsettings.Staging.json
  • {Environment}appsettings.{Environment}.json

4.1.2 配置的使用

假设我们需要在系统运行时获取系统名称、版本号及版权信息,这些信息可能随时变化而且需要在多个地方使用。这时就需要将这些信息配置起来。具体步骤如下:

4.1.2.1 配置 appsettings.json 信息

{  
  "AppInfo": {  
    "Name": "Furion",  
    "Version": "1.0.0",  
    "Company": "Baiqian"  
  }  
}  

特别注意appsettings.json 复制输出目录为如果较新则复制,生成操作为:内容

另外,某些 linux 系统不支持读取带 注释 的 json 文件,直接读取将会报错。需要将 json 内的注释全部 删除 才能正常读取。

4.1.2.2 读取 appsettings.json 信息

Furion 框架中,提供了两种读取方式:

  • 依赖注入 IConfiguration 对象读取
  • 通过 App.Configuration[path] 读取

  • App.Configuration[path]

  • 依赖注入方式
using Microsoft.AspNetCore.Mvc;  

namespace Furion.Web.Entry.Controllers  
{  
    [Route("api/[controller]")]  
    public class DefaultController : ControllerBase  
    {  
        [HttpGet]  
        public string Get()  
        {  
            return $@"名称:{App.Configuration["AppInfo:Name"]},  
                      版本:{App.Configuration["AppInfo:Version"]},  
                      公司:{App.Configuration["AppInfo:Company"]}";  
        }  
    }  
}  

using Microsoft.AspNetCore.Mvc;  
using Microsoft.Extensions.Configuration;  

namespace Furion.Web.Entry.Controllers  
{  
    [Route("api/[controller]")]  
    public class DefaultController : ControllerBase  
    {  
        [HttpGet]  
        public string Get([FromServices] IConfiguration configuration)  
        {  
            return $@"名称:{configuration["AppInfo:Name"]},  
                      版本:{configuration["AppInfo:Version"]},  
                      公司:{configuration["AppInfo:Company"]}";  
        }  
    }  
}  

依赖注入的方式通过依赖注入注入实例有几种方式:

  • 构造函数注入方式
private readonly IConfiguration _configuration;  
public DefaultController(IConfiguration configuration)  
{  
    _configuration = configuration;  
}  

  • 参数注入方式 [FromServices]
public string Get([FromServices] IConfiguration configuration)  
{  
}  

  • 属性注入方式
public IConfiguration Configuration { get; set; }  

想了解更多关于《ASP.NET Core - 依赖注入》 知识

4.1.2.3 如何选择读取方式

  • 在可依赖注入类中,依赖注入 IConfiguration 读取
  • 在静态类/非依赖注入类中,选择 App.Configuration[path] 读取

4.1.2.4 读取配置并转换成特定类型

ASP.NET CoreFurion 提供了多种配置类型读取并转换成特定类型,包括基础类型,对象类型,数组,集合,字典等等,如:

// ASP.NET Core  
var data = Configuration.GetSection("配置节点").Get<类型>();  

// Furion,推荐!!!  
var data = App.GetConfig<类型>("配置节点");  

4.1.3 路径符 查找节点

ASP.NET Core 中,配置采用 : 分隔符来读取分层配置数据。如上述例子中的 AppInfo:Name。如有更多层级数据则只需要通过 : 进入下一层节点即可。

假设我们有以下配置信息:

{  
  "AppInfo": {  
    "Name": "Furion",  
    "Version": "1.0.0",  
    "Company": {  
      "Name": "Baiqian",  
      "Address": {  
        "City": "中国",  
        "Province": "广东省",  
        "Detail": "中山市东区紫马公园西门"  
      }  
    }  
  }  
}  

  • 读取第二层
  • 读取第三层
  • 读取第四层
  • 读取第N层
var companyName = App.Configuration["AppInfo:Name"]; // => Furion  

var companyName = App.Configuration["AppInfo:Company:Name"]; // => Baiqian  

var companyName = App.Configuration["AppInfo:Company:Address:Detail"]; // => 中山市东区紫马公园西门  

var companyName = App.Configuration["AppInfo:Tier2:Tier3:Tier4...Tiern1:Tiern3..."]; // => 中山市东区紫马公园西门  

4.1.3.1 查找数组节点

有些时候我们需要或者数组特定的某些,可以通过 App.Configuration["array:0"] 获取,0 是索引数字。

4.1.4 自定义配置文件

XML 配置说明Furion v2.8.0 版本移除了 .xml 文件自动扫描配置了,改为手动添加配置。

大多情况下,我们的配置只需要在 appsettings.json 中配置即可,但一些特殊情况下,我们希望某些组件或功能拥有独立的配置,这个时候就需要用到自定义配置,Furion 目前支持 .json.xml 两种方式配置,如:

Furion.Web.Entry/emailsetting.json

{  
  "outlook": {  
    "smtp": {  
      "server": "smtp.office365.com",  
      "port": "587",  
      "ssl": "STARTTLS"  
    },  
    "pop": {  
      "server": "outlook.office365.com",  
      "port": "995",  
      "ssl": "TLS"  
    }  
  }  
}  

<?xml version="1.0" encoding="utf-8" ?>  
<configuration>  
  <MyKey>MyXMLFile Value</MyKey>  
  <Position>  
    <Title>Title from  MyXMLFile</Title>  
    <Name>Name from MyXMLFile</Name>  
  </Position>  
  <Logging>  
    <LogLevel>  
      <Default>Information</Default>  
      <Microsoft>Warning</Microsoft>  
    </LogLevel>  
  </Logging>  
</configuration>  

xml 配置事项如果采用 xml 配置,那么文件名必须以 .config.xml 结尾(不区分大小写)。

特别说明Furion 框架会在启动时自动扫描每一个项目层根目录下的 *.json 文件加入配置中,所以无需手工配置。

新增 *.json 文件的属性 复制到输出目录 设置为始终复制或较新复制,否则不会载入。另外配置文件不能出现重名,也就是保证整个项目中配置文件名字唯一。比如不能在非 Web 其他层定义 appsettings.json 文件。

v2.16.7+ 版本版本之后,支持自定义配置扫描目录:

{  
  "ConfigurationScanDirectories": ["目录1名称", "目录1名称/子目录名称"]  
}  

同时 Furion 提供了非常灵活的方式支持自定义配置文件读取,如:

4.1.4.1 读取 emailsetting.json 配置

读取自定义配置文件和读取 appsettings.json 一致,系统会自动从多个配置文件中读取输入,如:

  • App.Configuration[path]
  • 依赖注入方式
var smtpServer = App.Configuration["outlook:smtp:server"]; // => smtp.office365.com  

var smtpServer = _configuration["outlook:smtp:server"]; // => smtp.office365.com  

4.1.4.2 排除特定配置文件

有些时候,我们不需要 .json.xml 自动载入配置中,我们只需要在启动层 appsettings.json 中添加 IgnoreConfigurationFiles 节点即可:

{  
  "IgnoreConfigurationFiles": ["runtime.json"]  
}  

通配符支持Furion 4.8.8.22+ 版本支持完整的通配符支持,如:

{  
  "IgnoreConfigurationFiles": ["seed_*.json"]  
}  

额外知识:文件通配符语法

4.1.5 不同环境读取

在实际应用开发中,我们可能会根据不同的环境加载不同的配置文件,如 数据库连接字符串

这时我们只需要遵循特定命名规范 {name}.{Environment}.json 即可。如:

  • appsettings.Development.json
  • appsettings.Staging.json
  • appsettings.Production.json
  • emailsetting.Development.json
  • emailsetting.Staging.json
  • emailsetting.Production.json

这时,ASP.NET Core 会在应用启动时自动加载不同环境的配置文件。

4.1.6 配置更改通知(热更新

.NET Core 应用程序中,配置支持更改通知,也就是热更新操作。一旦监听到 appsettings.json 或自定义配置文件发生变动,就会触发 OnChange 方法。代码如下:

var appInfoConfiguration = App.Configuration.GetSection("AppInfo");  
ChangeToken.OnChange(() => App.Configuration.GetReloadToken(), () =>  
{  
  var name = appInfoConfiguration["Name"];  // 实时的最新值  
  var version = appInfoConfiguration["Version"];  // 实时的最新值  
});  

// 默认情况下,ChangeToken.OnChange 可能会触发两次,所以在 Furion v4.9.5.15+ 可更改为以下方式  
 ChangeToken.OnChange(() => App.Configuration.GetReloadToken(), ((Action)(() =>  
 {  
    var name = appInfoConfiguration["Name"];  // 实时的最新值  
    var version = appInfoConfiguration["Version"];  // 实时的最新值  
 })).Debounce()); // 添加了防抖操作  

监听对象如果监听全局配置文件传入 App.Configuration.GetReloadToken(),如果只需要监听特定节点,传入 App.Configuration.GetSection("AppInfo")

相关说明:https://gitee.com/dotnetchina/Furion/commit/feb85d21ae8e1f1a0dc215dd8b67419c70c8b7ce#note_32504730

4.1.7 手动添加配置文件

获取路径说明* 获取项目目录:AppContext.BaseDirectory * 获取网站根目录:Directory.GetCurrentDirectory()

有些时候,我们的配置文件没有放在项目的根目录下,这时候我们需要手动载入自定义配置文件,有以下几种方式:

  • 方式一:appsettings.json 中 (推荐)

支持版本在 v2.16.7+ 版本有效

{  
  "ConfigurationScanDirectories": ["目录1名称", "目录1名称/子目录名称"]  
}  

  • 方式二:.NET5Program.cs 中配置
public class Program  
{  
    public static void Main(string[] args)  
    {  
        CreateHostBuilder(args).Build().Run();  
    }  

    public static IHostBuilder CreateHostBuilder(string[] args) =>  
        Host.CreateDefaultBuilder(args)  
            .ConfigureAppConfiguration((hostingContext, config) =>  
            {  
                // 加载自定义配置  
                config.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true);  
            })  
            .ConfigureWebHostDefaults(webBuilder =>  
            {  
                webBuilder.UseStartup<Startup>();  
            });  
}  

  • 方式三:.NET6Program.cs 中配置
var builder = WebApplication.CreateBuilder(args)  
builder.Configuration.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true);  
// 注意先添加配置再初始化 Furion  
builder.Inject();  
var app = builder.Build();  
app.Run();  

如果使用 Serve.Run() 模式可使用下列代码配置:

Serve.Run(RunOptions.Default.ConfigureConfiguration((env, configuration) => {  
  configuration.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true);  
}));  

4.1.8 配置的优缺点

  • 优点

    • 能够在系统运行时快速读取
    • 无需额外配置
    • 缺点

    • 存在重复读取

    • 通过硬编码字符串读取,容易出错
    • 不能设置默认值
    • 不能在运行环境中动态配置
    • 不能验证配置有效性
    • 不支持更改通知

4.1.9 配置使用场景

如果只需要一次性读取配置信息,则使用配置,否则应该使用 《4.2 选项》代替。

4.1.10 实现配置中心

ASP.NET Core 除了通过配置文件读取配置信息外,还支持自定义 配置提供程序,通过 配置提供程序 可以实现配置中心,比如通过数据库提供配置。

具体实现查看微软官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view\=aspnetcore-5.0#custom-configuration-provider

使用 Nacos若使用 Nacos 可参考相关 Issuehttps://gitee.com/dotnetchina/Furion/issues/I6G02W

下面给出集成 AgileConfig 例子:

版本说明以下内容仅限 Furion 4.4.9 + 版本使用。

Serve.Run 方式:

Serve.Run(RunOptions.Default.WithArgs(args)  
    .ConfigureInject((builder, options) =>  
    {  
        options.ConfigureAppConfiguration((_, cfb) =>  
        {  
            cfb.AddAgileConfig(new AgileConfig.Client.ConfigClient(builder.Configuration), obj =>  
            {  
                Console.WriteLine($"{obj}");  
            });  
        });  

        options.ConfigureWebServices((_, services) =>  
        {  
            services.AddAgileConfig();  
        });  
    })  
);  

.NET6+ 方式

var builder = WebApplication.CreateBuilder(args)  
    .Inject((builder, options) =>  
    {  
        options.ConfigureAppConfiguration((_, cfb) =>  
        {  
            cfb.AddAgileConfig(new AgileConfig.Client.ConfigClient(builder.Configuration), obj =>  
            {  
                Console.WriteLine($"{obj}");  
            });  
        });  
        options.ConfigureWebServices((_, services) =>  
        {  
            services.AddAgileConfig();  
        });  
    });  

.NET5 方式:

public class Program  
{  
    public static void Main(string[] args)  
    {  
        CreateHostBuilder(args).Build().Run();  
    }  

    public static IHostBuilder CreateHostBuilder(string[] args) =>  
        Host.CreateDefaultBuilder(args)  
            .ConfigureWebHostDefaults(webBuilder =>  
            {  
                webBuilder  
                .Inject((builder, options) =>  
                {  
                    options.ConfigureAppConfiguration((_, cfb) =>  
                    {  
                        cfb.AddAgileConfig(new AgileConfig.Client.ConfigClient(cfb.Build()), obj =>  
                        {  
                            Console.WriteLine($"{obj}");  
                        });  
                    });  
                    options.ConfigureWebServices((_, services) =>  
                    {  
                        services.AddAgileConfig();  
                    });  
                })  
                .UseStartup<Startup>();  
            });  
}  

4.1.11 重载配置

Furion 会在应用启动的时候对 IConfiguration 进行静态缓存,如果使用了 App.Configuration 静态属性且配置数据已发生变更,则调用以下方法刷新即可:

App.Configuration.Reload();  

4.1.12 反馈与建议

与我们交流给 Furion 提 Issue


了解更多想了解更多 配置 知识可查阅 ASP.NET Core - 配置 章节。